package com.smile.service.impl;

import cn.dev33.satoken.session.SaSession;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.smile.api.OperateLogApi;
import com.smile.commons.action.ActionUtils;
import com.smile.commons.constant.StateConstant;
import com.smile.commons.page.MyBatisPlusPageConverter;
import com.smile.mapper.RoleMapper;
import com.smile.mapper.RoleMenuMapper;
import com.smile.mapper.UserMapper;
import com.smile.model.domain.SmilePlusRole;
import com.smile.model.domain.SmilePlusRoleMenu;
import com.smile.model.domain.SmilePlusUser;
import com.smile.model.dto.request.AddRoleRequestDTO;
import com.smile.model.dto.request.EditRoleRequestDto;
import com.smile.model.dto.request.GetRoleListRequestDTO;
import com.smile.model.response.response.GetRoleListResponseDTO;
import com.smile.model.response.response.GetStartingRoleResponseDTO;
import com.smile.request.AddOperateLogRequest;
import com.smile.service.RoleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

@Service
public class RoleServiceImpl implements RoleService {

    @Autowired
    private RoleMapper roleMapper;

    @Autowired
    private RoleMenuMapper roleMenuMapper;

    @Autowired
    private OperateLogApi operateLogApi;
    @Autowired
    private UserMapper userMapper;

    /**
     * 检查是否为超级管理员角色（ID为1）
     * @param roleId 角色ID
     * @param operation 操作类型（用于错误提示）
     */
    private void checkSuperRoleProtection(Long roleId, String operation) {
        if (roleId == 1) {
            throw new RuntimeException("超级管理员角色无法" + operation);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean addRole(AddRoleRequestDTO addRoleRequestDTO) {

        //TODO 这个角色这里还是有一点小问题


        if (ObjectUtil.isNotNull(addRoleRequestDTO)) {
            QueryWrapper<SmilePlusRole> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("delete_status", Boolean.FALSE)
                    .eq("role_name", addRoleRequestDTO.getRoleName())
                    .or().eq("role_value", addRoleRequestDTO.getRoleValue())
            ;
            List<SmilePlusRole> smilePlusRoles = roleMapper.selectList(queryWrapper);
            if (CollectionUtil.isNotEmpty(smilePlusRoles)) {
                throw new RuntimeException("该角色已存在");
            }
        }

        Long startTime = System.nanoTime();
        SmilePlusRole smilePlusRole = new SmilePlusRole();
        BeanUtil.copyProperties(addRoleRequestDTO, smilePlusRole);
        smilePlusRole.setUserId(Long.valueOf(StpUtil.getLoginId().toString()));
        smilePlusRole.setDeleteStatus(Boolean.FALSE);
        smilePlusRole.setCreateTime(LocalDateTime.now());
        smilePlusRole.setModifyTime(LocalDateTime.now());

        roleMapper.insert(smilePlusRole);

        addRoleRequestDTO.getMenuIds().forEach(menuId -> {
            SmilePlusRoleMenu smilePlusRoleMenu = new SmilePlusRoleMenu();
            smilePlusRoleMenu.setMenuId(menuId);
            smilePlusRoleMenu.setRoleId(smilePlusRole.getId());
            roleMenuMapper.insert(smilePlusRoleMenu);
        });
        Long endTime = System.nanoTime();

        AddOperateLogRequest addOperateLogRequest = new AddOperateLogRequest();
        addOperateLogRequest.setOperateModule("角色模块");
        addOperateLogRequest.setOperateName("添加角色");
        addOperateLogRequest.setOperateResult(Boolean.TRUE);
        addOperateLogRequest.setUserId(Long.valueOf(StpUtil.getLoginId().toString()));
        addOperateLogRequest.setOperateType(1);
        addOperateLogRequest.setIpAddress(ActionUtils.getIpInfo());
        addOperateLogRequest.setExplorer(ActionUtils.getExplorerInfo());
        addOperateLogRequest.setTimes(endTime - startTime);
        operateLogApi.addOperateLogRequest(addOperateLogRequest);

        return Boolean.TRUE;
    }


    @Override
    public Page<GetRoleListResponseDTO> getRoleList(GetRoleListRequestDTO getRoleListRequestDTO) {
        QueryWrapper<SmilePlusRole> queryWrapper = new QueryWrapper<>();
//        queryWrapper.eq("delete_status", false);
        if (StrUtil.isNotBlank(getRoleListRequestDTO.getRoleName())) {
            queryWrapper.eq("role_name", getRoleListRequestDTO.getRoleName());
        }
        if (ObjectUtil.isNotEmpty(getRoleListRequestDTO.getStatus())) {
            queryWrapper.eq("status", getRoleListRequestDTO.getStatus());
        }

        // 优先将超级管理员（id=1）置顶，其余按 sort 升序
        // 使用CASE WHEN实现更通用的排序逻辑
        queryWrapper.last("ORDER BY CASE WHEN id = 1 THEN 0 ELSE 1 END, sort ASC");

        Page<SmilePlusRole> page = new Page<>(getRoleListRequestDTO.getCurrentPage().longValue(), getRoleListRequestDTO.getPageSize().longValue());
        Page<SmilePlusRole> rolePage = roleMapper.selectPage(page, queryWrapper);

        return MyBatisPlusPageConverter.convertPage(rolePage, GetRoleListResponseDTO.class);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean editRole(EditRoleRequestDto editRoleRequestDto) {
        // 检查是否为超级管理员角色，防止编辑
        checkSuperRoleProtection(editRoleRequestDto.getId(), "编辑");

        Long startTime = System.nanoTime();

        if (ObjectUtil.isNotNull(editRoleRequestDto)) {
            if (StrUtil.isNotBlank(editRoleRequestDto.getRoleName()) || StrUtil.isNotBlank(editRoleRequestDto.getRoleValue())){
                QueryWrapper<SmilePlusRole> queryWrapper = new QueryWrapper<>();
                queryWrapper
                        .notIn("id", editRoleRequestDto.getId())
                        .eq("delete_status", Boolean.FALSE)
                        .eq(StrUtil.isNotBlank(editRoleRequestDto.getRoleName()), "role_name", editRoleRequestDto.getRoleName())
                        .or()
                        .eq(StrUtil.isNotBlank(editRoleRequestDto.getRoleValue()), "role_value", editRoleRequestDto.getRoleValue());
                System.out.println(queryWrapper.getSqlSelect());
                List<SmilePlusRole> smilePlusRoles = roleMapper.selectList(queryWrapper);
                if (CollectionUtil.isNotEmpty(smilePlusRoles) && !Objects.equals(smilePlusRoles.get(0).getId(), editRoleRequestDto.getId())) {
                    throw new RuntimeException("该角色已存在");
                }
            }
        }

        // 当角色状态变更为禁用时，提示在线用户“无权限操作”并强制踢下线
        if (ObjectUtil.isNotNull(editRoleRequestDto.getStatus())) {
            SmilePlusRole dbRole = roleMapper.selectById(editRoleRequestDto.getId());
            Integer newStatus = editRoleRequestDto.getStatus();
            if (ObjectUtil.isNotNull(dbRole)
                    && Objects.equals(newStatus, StateConstant.DISABLE_STATE)
                    && !Objects.equals(dbRole.getStatus(), StateConstant.DISABLE_STATE)) {
                QueryWrapper<SmilePlusUser> userQ = new QueryWrapper<>();
                userQ.eq("role_id", editRoleRequestDto.getId());
                userQ.eq("delete_status", Boolean.FALSE);
                List<SmilePlusUser> boundUsers = userMapper.selectList(userQ);
                if (CollectionUtil.isNotEmpty(boundUsers)) {
                    for (SmilePlusUser u : boundUsers) {
                        try {
                            try {
                                SaSession session = StpUtil.getSessionByLoginId(u.getId());
                                if (session != null) {
                                    session.set("msg", "无权限操作哦，请联系管理员");
                                }
                            } catch (Exception ignore) {}
                            StpUtil.kickout(u.getId());
                        } catch (Exception e) {
                            // ignore single-user failures and continue
                        }
                    }
                }
            }
        }

        if (CollectionUtil.isNotEmpty(editRoleRequestDto.getMenuIds())) {
            QueryWrapper<SmilePlusRoleMenu> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("role_id", editRoleRequestDto.getId());
            roleMenuMapper.delete(queryWrapper);
            editRoleRequestDto.getMenuIds().forEach(menuId -> {
                SmilePlusRoleMenu smilePlusRoleMenu = new SmilePlusRoleMenu();
                smilePlusRoleMenu.setMenuId(menuId);
                smilePlusRoleMenu.setRoleId(editRoleRequestDto.getId());
                roleMenuMapper.insert(smilePlusRoleMenu);
            });
        }

        UpdateWrapper<SmilePlusRole> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("id", editRoleRequestDto.getId());
        if (ObjectUtil.isNotNull(editRoleRequestDto.getStatus())) {
            updateWrapper.set("status", editRoleRequestDto.getStatus());
        }

        if (ObjectUtil.isNotNull(editRoleRequestDto.getSort())) {
            updateWrapper.set("sort", editRoleRequestDto.getSort());
        }
        if (StrUtil.isNotBlank(editRoleRequestDto.getRoleName())) {
            updateWrapper.set("role_name", editRoleRequestDto.getRoleName());
        }
        if (StrUtil.isNotBlank(editRoleRequestDto.getRoleValue())) {
            updateWrapper.set("role_value", editRoleRequestDto.getRoleValue());
        }

        updateWrapper.set("modify_time", LocalDateTime.now());
        roleMapper.update(new SmilePlusRole(), updateWrapper);
        Long endTime = System.nanoTime();

        AddOperateLogRequest addOperateLogRequest = new AddOperateLogRequest();
        addOperateLogRequest.setOperateModule("角色模块");
        addOperateLogRequest.setOperateName("修改角色");
        addOperateLogRequest.setOperateResult(Boolean.TRUE);
        addOperateLogRequest.setUserId(Long.valueOf(StpUtil.getLoginId().toString()));
        addOperateLogRequest.setOperateType(2);
        addOperateLogRequest.setIpAddress(ActionUtils.getIpInfo());
        addOperateLogRequest.setExplorer(ActionUtils.getExplorerInfo());
        addOperateLogRequest.setTimes(endTime - startTime);
        operateLogApi.addOperateLogRequest(addOperateLogRequest);

        return Boolean.TRUE;
    }

    @Override
    public Boolean deleteRole(Long id) {
        // 检查是否为超级管理员角色，防止删除
        checkSuperRoleProtection(id, "删除");

        Long startTime = System.nanoTime();
        QueryWrapper<SmilePlusUser> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("role_id", id);
        List<SmilePlusUser> smilePlusRoles = userMapper.selectList(queryWrapper);
        if (CollectionUtil.isNotEmpty(smilePlusRoles)) {
            return Boolean.FALSE;
        }
        roleMapper.deleteById(id);
        Long endTime = System.nanoTime();

        AddOperateLogRequest addOperateLogRequest = new AddOperateLogRequest();
        addOperateLogRequest.setOperateModule("角色模块");
        addOperateLogRequest.setOperateName("删除角色");
        addOperateLogRequest.setOperateResult(Boolean.TRUE);
        addOperateLogRequest.setUserId(Long.valueOf(StpUtil.getLoginId().toString()));
        addOperateLogRequest.setOperateType(3);
        addOperateLogRequest.setIpAddress(ActionUtils.getIpInfo());
        addOperateLogRequest.setExplorer(ActionUtils.getExplorerInfo());
        addOperateLogRequest.setTimes(endTime - startTime);
        operateLogApi.addOperateLogRequest(addOperateLogRequest);

        return Boolean.TRUE;
    }

    @Override
    public GetRoleListResponseDTO getRoleById(Long id) {
        SmilePlusRole smilePlusRole = roleMapper.selectById(id);
        if (ObjectUtil.isNull(smilePlusRole)) {
            return null;
        }

        if (smilePlusRole.getDeleteStatus()) {
            throw new RuntimeException("此角色已删除");
        }
        QueryWrapper<SmilePlusRoleMenu> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("role_id", smilePlusRole.getId());
        List<SmilePlusRoleMenu> smilePlusRoleMenus = roleMenuMapper.selectList(queryWrapper);
        List<Long> collect = smilePlusRoleMenus.stream().map(i -> {
            return i.getMenuId();
        }).collect(Collectors.toList());


        GetRoleListResponseDTO getRoleListResponseDTO = new GetRoleListResponseDTO();

        BeanUtil.copyProperties(smilePlusRole, getRoleListResponseDTO);
        getRoleListResponseDTO.setMenuIds(collect);
        return getRoleListResponseDTO;
    }

    @Override
    public List<GetStartingRoleResponseDTO> getStartingRole() {
        QueryWrapper<SmilePlusRole> queryWrapper = new QueryWrapper<>();
        // 取消只查询开启状态的角色.eq("status", StateConstant.OPENING_STATE)
        queryWrapper.eq("delete_status", Boolean.FALSE);
        return BeanUtil.copyToList(roleMapper.selectList(queryWrapper), GetStartingRoleResponseDTO.class);
    }
}
